home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 20
/
Cream of the Crop 20 (Terry Blount) (1996).iso
/
program
/
commio0b.zip
/
ASYNC.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-11-21
|
25KB
|
819 lines
; Status byte definition (C_Status):
; 7 6 5 4 3 2 1 0
; | | | | | | | |____ Input buffer empty
; | | | | | | |________ Input buffer full
; | | | | | |____________ Output buffer empty
; | | | | |________________ Output buffer full
; | | | |____________________ Input buffer overflow
; | | |________________________ Output buffer overflow
; | |____________________________ Hard handshake active (xmit stopped)
; |________________________________ Soft handshake active (xmit stopped)
; Control byte definition (C_Ctrl):
; 7 6 5 4 3 2 1 0
; | | | | | | | |____ Enable RTS handshake
; | | | | | | |________ Enable CTS handshake
; | | | | | |____________ Enable software handshake
; | | | | |________________
; | | | |____________________
; | | |________________________
; | |____________________________
; |________________________________
;********************************************************
; Macro: PutChar
; Function: Place character in transmit buffer (transmit a character)
; Entry: AL <- Port # (0-3)
; AH <- Status register
; BX <- Byte array pointer
; CH <- Character to put in buffer
; DX <- Base address of port
; Destroyed: ES,SI,DI,AL
; Note: Port address passed is NOT checked for validity.
; Subroutine ChkPort will create the proper entry environment
PUTCHAR MACRO
test ah, 00001000b ;Is buffer full?
JZ @@putch1 ;No, OK to put character
or ah, 00100000b ;set overflow flag
JMP @@putchx ;and exit
@@putch1:
shl bl,1 ;bx <- word array index
mov di, [C_outhead+bx] ;bump the head pointer
mov si, [c_outtail+bx]
inc di
cmp di, [C_outsize+bx]
jb @@putch2
xor di,di
@@putch2:
mov [C_outhead+bx],di ;save head pointer
inc [C_buffull+bx] ;increment buffer-full word
shl bl,1 ;BX <- pointer array index
LES BX, [C_outbufptr+bx] ;Load ES with segment of output buf
mov [ES:BX+DI],ch ;save the byte
cmp di, si ;Is output buffer full?
jnz @@putch3 ;no, go enable xmitter
or ah, 00001000b ;Set status to output buffer full
@@putch3:
xor bh, bh
mov bl, al ;Save AL in BL and make BX byte index
test ah, 11000000b ;soft/hard handshake on?
jnz @@putchx
; test ah, 00000100b
; jz @@putchx
and ah, 11111011b ;Buffer is no longer empty
inc dl ;Change to IER register
in al, dx ;Read in the IER
or al, 00000010b ;Turn on xmt interrupt
NOP ;Slow down for slow machines
NOP
out dx, al ;Write out the IER
dec dl ;Back to base reg
@@putchx:
mov [C_status+bx],ah ;set status byte
; mov al,bl ;get port num back in AL
ENDM
;******************************************************************
; MACRO: Test for modem status change
;
; Entry: DX - port base
; BX - byte array index
;
; Destroyed: AX, CX
MSCHG MACRO
; Get modem status & control/status registers
@@Msc0: ADD DL,MSR ;DX <- 8250 MSR port address
IN AL,DX ;AL <- 8250 Modem status
SUB DL,MSR ;Back to base
MOV CL,[C_Status+BX] ;CL <- Status register
MOV CH,[C_Ctrl+BX] ;CH <- Control register
; Control CTS status flag based on CTS status and handshake enable
TEST CH,00000010b ;CTS handshake enabled ?
JZ @@Msc2 ; No, ignore CTS status
TEST AL,00010000b ;CTS asserted ?
JNZ @@Msc1 ; Yes, enable transmit
OR CL,01000000b ;CTS inactive - hard handshake on
JMP @@Msc2 ;
@@Msc1: AND CL,10111111b ;CTS active - hard handshake off
@@Msc2: MOV [C_Status+BX],CL ;Save status flags
; Determine if transmitter should be enabled
@@Msc3: ADD DL,IER ;DX <- 8250 IER port address
IN AL,DX ;AL <- Interrupt enable register
OR AL,00000010b ;Enable transmitter by default
TEST CL,11000100b ;Enable transmitter ?
JZ @@Msc4 ; Yes
AND AL,11111101b ; No - disable transmitter
@@Msc4: OUT DX,AL ;Update IER
SUB DL, IER
ENDM
IDEAL
SEGMENT DATA WORD PUBLIC
; Externally accessed (TP program) variables
; Note: Most of these variables are declared as arrays in the main
; program; i.e. C_InSize : Array[1..4] Of Word
EXTRN C_InBufPtr :DWORD ;Pointer to input buffers
EXTRN C_OutBufPtr:DWORD ;Pointer to output buffers
EXTRN C_InSize :WORD ;Size (bytes) of input buffers
EXTRN C_OutSize :WORD ;Size (bytes) of output buffers
EXTRN C_InHead :WORD ;Input (receive) head pointers
EXTRN C_OutHead :WORD ;Output (transmit) head pointers
EXTRN C_InTail :WORD ;Input (receive) tail pointers
EXTRN C_OutTail :WORD ;Output (transmit) tail pointers
EXTRN C_RTSOn :WORD ;Point at which RTS line is asserted
EXTRN C_RTSOff :WORD ;Point at which RTS line is dropped
EXTRN C_StartChar:BYTE ;Start character for soft handshake
EXTRN C_StopChar :BYTE ;Stop character for soft handshake
EXTRN C_Status :BYTE ;Status byte (see above)
EXTRN C_Ctrl :BYTE ;Control byte (see above)
EXTRN C_PortOpen :BYTE ;Port-open flags
EXTRN C_PortAddr :WORD ;Base address of ports
EXTRN C_MaxCom :BYTE ;Highest port # defined (single byte)
EXTRN C_bufFull :WORD
EXTRN C_cascade :BYTE
; EXTRN C_CharSend :WORD
; EXTRN C_CharWrite :WORD
; EXTRN C_Temp :WORD ;Used for debugging
; 8250 register offsets
IER EQU 1 ;Interrupt enable register
IIR EQU 2 ;Interrupt identification register
LCR EQU 3 ;Line control register
MCR EQU 4 ;Modem control register
LSR EQU 5 ;Line status register
MSR EQU 6 ;Modem status register
SCR EQU 7 ;8250 scratch register
ENDS DATA
; Code segment declaration
SEGMENT CODE BYTE PUBLIC
ASSUME CS:CODE,DS:DATA
; Externally accessable procedures defined here
PUBLIC INT_Handler
PUBLIC ComReadCh
PUBLIC ComReadChW
PUBLIC ComWriteCh
PUBLIC ComWriteChW
;********************************************************
;* *
;* Subroutines that are used internally *
;* *
;********************************************************
; Subroutine: ChkPort
; Function: Check port parameter(s), ensure that port is OPEN
; Entry: AL <- Port # (1 - C_MaxCom)
; Exit: AL -> Adjusted port # (0 - 3)
; AH -> Status register
; BX -> Byte array index
; DX -> Base address of port
; Carry flag SET if parameters & port are OK
;
; PROC ChkPort FAR
;
; Determine if port # is valid
;
; CMP AL,[C_MaxCom] ;Port # > Maximum port # ?
; JA ChkErr ; Yes, exit w/error
; CMP AL,0 ;Port # = 0 (invalid port #)
; JZ ChkErr ; Yes, exit w/error
; DEC AL ;AL <- Adjusted port #
;
; Check if port open
;
; XOR BH,BH ;
; MOV BL,AL ;BX <- Byte array index
; MOV AH,[C_PortOpen+BX] ;AH <- Port-open flag
; CMP AH,0 ;Port open ?
; JZ ChkErr ; No, exit w/error
;
; Get status register and base port address in DX
;
; MOV AH,[C_Status+BX] ;AH <- Status register
; SHL BL,1 ;BX <- Word array index
; MOV DX,[C_PortAddr+BX] ;DX <- Port address
; SHR BL,1 ;BX <- Byte array index
; STC ;Set carry (valid return)
; RET ;Exit
;
; Here if error
;
;ChkErr: CLC ;Clear carry (invalid return)
; RET ;Exit
;
; ENDP ChkPort
; PROC PutChar FAR
;
;; Check for buffer overflow
;
; TEST AH,00001000b ;Buffer full ?
; JZ PutCh1 ; No, continue
; OR AH,00100000b ;Set buffer-overflow flag
; JMP PutChX ;Exit
;
;; Increment head pointer
;
;PutCh1: SHL BL,1 ;BX <- Word array index
; MOV DI,[C_OutHea